package com.chinasoft.maysham.manager.service.user.impl;

import com.chinasoft.maysham.manager.exception.BizException;
import com.chinasoft.maysham.manager.model.User;
import com.chinasoft.maysham.manager.model.UserStatus;
import com.chinasoft.maysham.manager.repo.user.UserRepo;
import com.chinasoft.maysham.manager.request.UserRegisterReq;
import com.chinasoft.maysham.manager.service.project.ProjectUserService;
import com.chinasoft.maysham.manager.service.user.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepo userRepo;

    @Resource
    private ProjectUserService projectUserService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public User register(UserRegisterReq registerReq, String userId) {
        if (userRepo.exist(Criteria.where("username").is(registerReq.getUsername()).and("deleted").is(false), User.class)) {
            throw new BizException("username duplicated");
        }
        User user = new User(registerReq.getUsername(), registerReq.getPassword());
        user.setNickName(registerReq.getNickName());
        user.setStatus(UserStatus.READY);
        user.setResourceId(registerReq.getResourceId());
        user.setResourceType(registerReq.getResourceType());
        user.setMemo(registerReq.getMemo());
        user.setIcon(registerReq.getIcon());
        user.setDescription(registerReq.getDescription());
        return userRepo.save(user);
    }

    @Override
    public List<User> list(int page, int size, String keyword, String userId) {
        return userRepo.list(PageRequest.of(page, size), keyword);
    }

    @Override
    public Boolean unRegister(String userId, String opId) {
        projectUserService.unRegisterUser(userId);
        return userRepo.deleteById(userId, User.class);
    }

    @Override
    public User update(String userId, UserRegisterReq registerReq, String currentUserId) {
        User user = userRepo.findById(userId, User.class);
        if (user == null) {
            throw new BizException("userId invalid");
        }
        if (!StringUtils.isEmpty(registerReq.getNickName())) {
            user.setNickName(registerReq.getNickName());
        }
        if (!StringUtils.isEmpty(registerReq.getMemo())) {
            user.setMemo(registerReq.getMemo());
        }
        if (!StringUtils.isEmpty(registerReq.getIcon())) {
            user.setIcon(registerReq.getIcon());
        }
        if (!StringUtils.isEmpty(registerReq.getDescription())) {
            user.setDescription(registerReq.getDescription());
        }
        return userRepo.save(user);
    }

    @Override
    public User login(String username, String password) {

        // 目前只查询用户是否存在，不比较密码
        User user = userRepo.findByUsername(username);
        if (user == null) {
            throw new BizException("username invalid");
        }
        // 获取用户的token并返回
        addToken(user);
        return user;
    }

    private void addToken(User user) {
        ValueOperations<String, String> value = redisTemplate.opsForValue();
        String token = value.get(user.getId());
        user.setToken(token);
    }

    @Override
    public UserDetails loadUserByUsername(String username) {
        return userRepo.findByUsername(username);
    }
}
